package bb.lanxing;

import static android.app.ActivityManager.MOVE_TASK_WITH_HOME;
import static android.content.Context.ACTIVITY_SERVICE;
import static android.content.Context.POWER_SERVICE;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.util.Log;
import android.util.SparseArray;

import com.bes.bessdk.BesSdkConstants;
import com.bes.bessdk.utils.SPHelper;

import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.annotation.Nonnull;

public class AppLifecycle {
    private static final String TAG = "AppLifecycle";
    private static AppLifecycle instance;
    private boolean isForeground;
    private boolean isVisibleToUser;
    private final LinkedList<Integer> keyForTopActivity = new LinkedList<>();
    private SparseArray<WeakReference<Activity>> mActivities = new SparseArray<>();
    private final Application.ActivityLifecycleCallbacks lifeCircleCallback = new Application.ActivityLifecycleCallbacks() {
        @Override
        public void onActivityCreated(Activity activity, Bundle bundle) {
            Log.v(AppLifecycle.TAG, "onActivityCreated: " + activity.getClass().getName());
        }

        @Override
        public void onActivityStarted(final Activity activity) {
            Log.v(AppLifecycle.TAG, "onActivityStarted: " + activity.getClass().getName());
            AppLifecycle.this.keyForTopActivity.addLast(activity.hashCode());
            AppLifecycle.this.mActivities.put(activity.hashCode(), new WeakReference(activity));
            AppLifecycle.this.onActivityChanged();
        }

        @Override
        public void onActivityResumed(Activity activity) {
            Log.v(AppLifecycle.TAG, "onActivityResumed: " + activity.getClass().getName());
            AppLifecycle.this.isVisibleToUser = true;
        }

        @Override
        public void onActivityPaused(Activity activity) {
            Log.v(AppLifecycle.TAG, "onActivityPaused: " + activity.getClass().getName());
            AppLifecycle.this.isVisibleToUser = false;
        }

        @Override
        public void onActivityStopped(final Activity activity) {
            Log.v(AppLifecycle.TAG, "onActivityStopped: " + activity.getClass().getName());
            AppLifecycle.this.mActivities.remove(activity.hashCode());

            keyForTopActivity.remove(Integer.valueOf(activity.hashCode()));
            AppLifecycle.this.onActivityChanged();
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
            Log.v(AppLifecycle.TAG, "onActivitySaveInstanceState: " + activity.getClass().getName());
        }

        @Override
        public void onActivityDestroyed(Activity activity) {
            SPHelper.putPreference(activity, BesSdkConstants.BES_BLE_KEY_ELPO_RUNNING_FLAG, 0);
            SPHelper.putPreference(activity, BesSdkConstants.BES_BLE_KEY_ELPO_CMD_ID, 0);
            Log.v(AppLifecycle.TAG, "onActivityDestroyed: " + activity.getClass().getName());
        }
    };
    private final Runnable activityTrack = () -> {
        SparseArray sparseArray = new SparseArray();
        for (int i = 0; i < AppLifecycle.this.mActivities.size(); i++) {
            int keyAt = AppLifecycle.this.mActivities.keyAt(i);
            WeakReference weakReference = AppLifecycle.this.mActivities.get(keyAt);
            Activity activity = (Activity) weakReference.get();
            if (activity != null && !activity.isFinishing()) {
                sparseArray.put(keyAt, weakReference);
            }
        }
        AppLifecycle.this.mActivities = sparseArray;
        boolean z = AppLifecycle.this.isForeground;
        AppLifecycle appLifecycle = AppLifecycle.this;
        appLifecycle.isForeground = appLifecycle.mActivities.size() > 0;
        if (AppLifecycle.this.isForeground != z) {
            Iterator it = AppLifecycle.this.listeners.iterator();
            while (it.hasNext()) {
                OnStatueChangedListener onStatueChangedListener = (OnStatueChangedListener) it.next();
                if (AppLifecycle.this.isForeground) {
                    onStatueChangedListener.onForeground();
                } else {
                    onStatueChangedListener.onBackground(!AppLifecycle.this.isScreenOn());
                }
            }
        }
    };
    private final Handler handler = new Handler(Looper.getMainLooper());
    private final CopyOnWriteArrayList<OnStatueChangedListener> listeners = new CopyOnWriteArrayList<>();

    public interface OnStatueChangedListener {
        void onBackground(boolean offScreen);

        void onForeground();
    }

    public void onActivityChanged() {
        this.handler.removeCallbacks(this.activityTrack);
        this.handler.postDelayed(this.activityTrack, 300L);
    }

    public boolean isActivityExist(Class<?> clazz) {
        if (clazz == null) {
            return false;
        }
        for (int i = 0; i < this.mActivities.size(); i++) {
            Activity activity = this.mActivities.get(this.mActivities.keyAt(i)).get();
            if (activity != null && !activity.isFinishing() && activity.getClass().equals(clazz)) {
                return true;
            }
        }
        return false;
    }

    public int indexOf(Class<?> clazz) {
        if (clazz == null) {
            return -1;
        }
        for (int i = 0; i < this.mActivities.size(); i++) {
            Activity activity = this.mActivities.get(this.mActivities.keyAt(i)).get();
            if (activity != null && !activity.isFinishing() && activity.getClass().equals(clazz)) {
                return i;
            }
        }
        return -1;
    }

    public Activity getTopActivity() {
        WeakReference<Activity> weakReference = this.mActivities.get(keyForTopActivity.getLast());
        if (weakReference != null) {
            return weakReference.get();
        }
        return null;
    }

    public boolean isVisibleToUser() {
        return this.isVisibleToUser;
    }

    public boolean registerOnStatueChangedListener(OnStatueChangedListener listener) {
        return this.listeners.add(listener);
    }

    public boolean unregisterOnStatueChangedListener(OnStatueChangedListener listener) {
        return this.listeners.remove(listener);
    }

    private AppLifecycle(Application context) {
    }

    public static void init(Application app) {
        if (instance == null) {
            AppLifecycle appLifecycle = new AppLifecycle(app);
            instance = appLifecycle;
            app.registerActivityLifecycleCallbacks(appLifecycle.lifeCircleCallback);
        }
    }

    public static void release(Application app) {
        AppLifecycle appLifecycle = instance;
        if (appLifecycle != null) {
            app.unregisterActivityLifecycleCallbacks(appLifecycle.lifeCircleCallback);
            instance.listeners.clear();
            instance = null;
        }
    }

    public static AppLifecycle get() {
        return instance;
    }

    public boolean isForeground() {
        return this.isForeground;
    }

    public boolean isScreenOn() {
        PowerManager powerManager = (PowerManager) App.getContext().getSystemService(POWER_SERVICE);
        if (Build.VERSION.SDK_INT < 20) {
            return powerManager.isScreenOn();
        }
        return powerManager.isInteractive();
    }

    public static void moveToFront(@Nonnull Context appContext) {
        if (Build.VERSION.SDK_INT >= 11) {
            ActivityManager activityManager = (ActivityManager) appContext.getSystemService(ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> runningTasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
            for (int i = 0; i < runningTasks.size(); i++) {
                if (runningTasks.get(i).baseActivity.toShortString().indexOf(BuildConfig.APPLICATION_ID) > -1) {
                    activityManager.moveTaskToFront(runningTasks.get(i).id, MOVE_TASK_WITH_HOME);
                }
            }
        }
    }
}